package com.cn.redis.service.impl;


import com.cn.redis.exception.ClockMovedBackException;
import com.cn.redis.exception.NoBitException;
import com.cn.redis.properties.SnowFlowerProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import com.cn.redis.service.a;

@Service("com.cn.redis.gen.b")
public class b implements a {
    @Resource(
            name = "com.cn.redis.properties.sf"
    )
    SnowFlowerProperties H;
    private static final Logger I = LoggerFactory.getLogger(b.class);
    private long J = -1L;
    private long workerId;
    private long K = 0L;
    private long lastTimestamp = -1L;
    private static final Random L = new Random();
    Map<String, Long> M = new HashMap();

    public b() {
    }

    public boolean init() {
        return true;
    }

    public synchronized Long d(String key) {
        long id = -1L;
        this.workerId = this.H.y();
        if (this.workerId >= 0L && this.workerId <= this.H.B()) {
            long timestamp = this.H();
            if (timestamp < this.lastTimestamp) {
                long refusedSeconds = (this.lastTimestamp - timestamp) / 1000L;
                throw new ClockMovedBackException("Clock moved backwards. Refusing for %d seconds", new Object[]{refusedSeconds});
            } else {
                if (this.lastTimestamp == timestamp) {
                    this.K = this.K + 1L & this.H.E();
                    if (this.K == 0L) {
                        this.K = (long)L.nextInt(100);
                        timestamp = this.k(this.lastTimestamp);
                    }
                } else {
                    this.K = (long)L.nextInt(100);
                }

                this.lastTimestamp = timestamp;
                if ("et".equals(this.H.x())) {
                    this.J = 8796093022208L;
                    id = timestamp + this.J << (int)this.H.D() | this.workerId << (int)this.H.C() | this.K;
                } else {
                    if (!"st".equals(this.H.x())) {
                        throw new NoBitException();
                    }

                    this.J = 1525278457256L;
                    id = timestamp - this.J << (int)this.H.D() | this.workerId << (int)this.H.C() | this.K;
                }

                return id;
            }
        } else {
            throw new IllegalArgumentException(String.valueOf("workerID must gte 0 and lte " + this.H.B()));
        }
    }

    protected long k(long lastTimestamp) {
        long timestamp;
        for(timestamp = this.H(); timestamp <= lastTimestamp; timestamp = this.H()) {
        }

        return timestamp;
    }

    protected long H() {
        return System.currentTimeMillis();
    }
}
